package com.tuo51.components.redis.impl;

import com.tuo51.components.redis.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created by Ron.Yao
 * on 2017/3/19.
 *
 * @author: yaoting@digitalchina.com
 * @version: 1.0
 */
@Service
public class RedisServiceImpl implements RedisService {

    private RedisTemplate redisTemplate;

    private byte[] rawKey;

    private BoundListOperations<String,String> listOperations;//noblocking

    @Autowired(required = false)
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(stringSerializer);
        this.redisTemplate = redisTemplate;
    }
    @Override
    public Set<String> getKeys(String pattern) {
        return redisTemplate.keys(pattern);
    }

    @Override
    public void pushFromHead(String key, String value) {
        bindKeys(key);
        listOperations.leftPush(value);
    }

    @Override
    public void pushFromTail(String key, String value) {
        bindKeys(key);
        listOperations.rightPush(value);
    }

    @Override
    public String removeFromHead(String key) {
        bindKeys(key);
        return listOperations.leftPop();
    }

    @Override
    public String removeFromTail(String key) {
        bindKeys(key);
        return listOperations.rightPop();
    }

    @Override
    public Long getKeySize(String key) {
        bindKeys(key);
        return listOperations.size();
    }

    private void bindKeys(String key) {
        rawKey = redisTemplate.getKeySerializer().serialize(key);
        listOperations = redisTemplate.boundListOps(key);
    }



    @Override
    public void saveMap(final String key, Map map) {
        redisTemplate.opsForHash().putAll(key, map);
    }

    @Override
    public void saveMap(final String key, long expireTime, Map map) {
        saveMap(key, map);
        redisTemplate.expire(key, expireTime,TimeUnit.SECONDS);
    }

    @Override
    public void saveValue(final String key, String value){
        redisTemplate.boundValueOps(key).set(value);
    }

    @Override
    public void saveValue(final String key, long expireTime, String value){
        saveValue(key, value);
        redisTemplate.expire(key, expireTime,TimeUnit.SECONDS);
    }
    @Override
    public void refreshTime(final String key, long expireTime){
        redisTemplate.expire(key, expireTime,TimeUnit.SECONDS);
    }


    @Override
    public String getValue(String key) {
        if (Objects.isNull(redisTemplate.opsForValue().get(key)))
            return null;
        return redisTemplate.opsForValue().get(key).toString();
    }

    @Override
    public boolean deleteLike(String key) {
        Set<String> keys = redisTemplate.keys(key + "*");
        redisTemplate.delete(keys);
        return true;
    }

    @Override
    public Map getMap(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    @Override
    public boolean delKey(String key) {
        redisTemplate.delete(key);
        return true;
    }

    // 示例：RedisService 中的 set 方法
    public void set(String key, String value, int expire, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, expire, unit);
    }
}
